package com.yuyou.fn.educational.service.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.educational.entity.AttendanceRecordDetail;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.entity.StudentReg;
import com.yuyou.fn.educational.service.IAttendanceRecordDetailService;
import com.yuyou.fn.educational.service.ICourseClassService;
import com.yuyou.fn.educational.service.IFinishLectureService;
import com.yuyou.fn.educational.vo.AttendanceRecordDetailUpdateVo;
import org.springframework.stereotype.Service;

import com.yuyou.fn.educational.mapper.AttendanceRecordMapper;
import com.yuyou.fn.educational.entity.AttendanceRecord;
import com.yuyou.fn.educational.service.IAttendanceRecordService;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * AttendanceRecord 表数据服务层接口实现类
 *
 */
@Service
public class AttendanceRecordServiceImpl extends SuperServiceImpl<AttendanceRecordMapper, AttendanceRecord,Long> implements IAttendanceRecordService {

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IFinishLectureService finishLectureService ;

    @Resource
    private IAttendanceRecordDetailService attendanceRecordDetailService ;

    @Override
    public void createAttendanceRecordForStudent(List<StudentReg> studentRegList) {
        for(StudentReg studentReg : studentRegList ){
            createAttendanceRecordForStudent(studentReg.getClassId()  ,studentReg.getStudentId() ,studentReg.getStudentName());
        }
    }

    @Override
    public void createAttendanceRecord(Long classId, Integer lectureAmount) {
        List<AttendanceRecord> list  = new ArrayList<>(lectureAmount);
        for(int i = 1 ;i <= lectureAmount ;i++ ){
            AttendanceRecord attendanceRecord = new AttendanceRecord();
            attendanceRecord.setClassId(classId);
            attendanceRecord.setLectureNo(i);
            attendanceRecord.setUpdateTime(TimeUtils.now());
            attendanceRecord.setCreateTime(TimeUtils.now());
            attendanceRecord.setAbsenceAmount(0);
            attendanceRecord.setAttendanceAmount(0);
            attendanceRecord.setLateAmount(0);
            attendanceRecord.setLeaveAmount(0);
            attendanceRecord.setStatus(0);
            attendanceRecord.setTotalAmount(0);
            list.add(attendanceRecord);
        }
        insertBatch(list) ;

    }


    @Override
    public void createAttendanceRecordForStudent(Long classId, Long studentId,String studentName) {
        List<AttendanceRecord> recordList = findAttendanceRecordByClassId(classId);
        if(recordList == null || recordList.isEmpty() ){
            CourseClass courseClass = courseClassService.findById(classId);
            createAttendanceRecord(classId,courseClass.getLectureAmount());
            recordList = findAttendanceRecordByClassId(classId);
        }

        List<AttendanceRecordDetail> detailList = new ArrayList<>(20);
        for(AttendanceRecord attendanceRecord : recordList ){
            AttendanceRecordDetail attendanceRecordDetail = new AttendanceRecordDetail();
            attendanceRecordDetail.setAttendanceStatus(0);
            attendanceRecordDetail.setCreateTime(TimeUtils.now());
            attendanceRecordDetail.setRecordId(attendanceRecord.getRecordId());
            attendanceRecordDetail.setStudentId(studentId);
            attendanceRecordDetail.setUpdateTime(TimeUtils.now());
            attendanceRecordDetail.setStudentName(studentName);
            detailList.add(attendanceRecordDetail);
        }

        attendanceRecordDetailService.insertBatch(detailList) ;
        List<Long> recordIds = BeanUtils.toList(recordList,"recordId");
        updateTotalAmount(recordIds) ;

    }

    private void updateTotalAmount(List<Long> recordIds ) {
        for(Long  recordId : recordIds ){
            Integer amount  = attendanceRecordDetailService.countByRecordId(recordId);
            AttendanceRecord update = new AttendanceRecord();
            update.setRecordId(recordId);
            update.setTotalAmount(amount);
            updateSelectiveById(update);
        }
    }

    @Override
    public List<AttendanceRecord> findAttendanceRecordByClassId(Long classId) {
        Example<AttendanceRecord> example = AttendanceRecord.createExample();
        example.orderBy("lectureNo");
        example.createCriteria().andEqualTo("classId",classId);
        return findListByExample(example);
    }

    @Override
    public List<AttendanceRecordDetail> findAttendanceRecordDetailByRecordId(Long recordId) {
        Example<AttendanceRecordDetail> example = AttendanceRecordDetail.createExample();
        example.createCriteria().andEqualTo("recordId",recordId);
        return attendanceRecordDetailService.findListByExample(example);
    }


    @Transactional
    @Override
    public void updateAttendanceRecordDetail(Long recordId, List<AttendanceRecordDetailUpdateVo> details) {
        //检查前一讲是否考勤了

        AttendanceRecord record = findById(recordId);
        AttendanceRecord preAttendanceRecord = findAttendanceRecordByClassIdLectureNo(record.getClassId(), record.getLectureNo() - 1);
        if(preAttendanceRecord != null && preAttendanceRecord.getStatus() != 1 ){
            throw new BusException("【第"+preAttendanceRecord.getLectureNo()+"讲】未考勤");
        }

        Map<Integer,Integer> count = new HashMap<>();

        for(AttendanceRecordDetailUpdateVo d : details ){
            AttendanceRecordDetail update = new AttendanceRecordDetail();
            BeanUtils.copyProperties(update,d );
            attendanceRecordDetailService.updateSelectiveById(update);
            Integer num = count.get(update.getAttendanceStatus());
            if(num == null ){
                num = 0 ;
            }
            count.put(update.getAttendanceStatus(),num + 1 );
        }

        boolean b = courseClassService.updateCompletedLectureAmount(record.getClassId(),record.getLectureNo());

        if(b){
            finishLectureService.addFinishLecture(record.getClassId(),record.getLectureNo());
        }

        AttendanceRecord update = new AttendanceRecord();
        update.setRecordId(recordId);
        update.setStatus(1);
        update.setAttendanceTime(TimeUtils.now());
        update.setAttendanceAmount(count.get(0) == null ? 0 : count.get(0) );
        update.setAbsenceAmount(count.get(1) == null ? 0 : count.get(1) );
        update.setLateAmount(count.get(2) == null ? 0 : count.get(2) );
        update.setLeaveAmount(count.get(3) == null ? 0 : count.get(3) );
        updateSelectiveById(update);

    }

    public AttendanceRecord findAttendanceRecordByClassIdLectureNo(Long classId, Integer lectureNo) {
        Example<AttendanceRecord> example = AttendanceRecord.createExample();
        example.createCriteria().andEqualTo("classId",classId).andEqualTo("lectureNo",lectureNo);
        return findOneByExample(example);

    }



    @Transactional
    @Override
    public void deleteAttendanceRecordForStudent(Long classId, Long studentId, Integer startLectureNo, Integer endLectureNo) {
        List<AttendanceRecord> attendanceRecordList = findAttendanceRecordByClassId(classId);
        List<Long> recordIds = new ArrayList<>(attendanceRecordList.size());

        for(AttendanceRecord attendanceRecord : attendanceRecordList ){
            if(attendanceRecord.getStatus() == 0 && attendanceRecord.getLectureNo().intValue() >= startLectureNo.intValue() && attendanceRecord.getLectureNo().intValue() <= endLectureNo.intValue() ){
                recordIds.add(attendanceRecord.getRecordId());
            }
        }

        Example<AttendanceRecordDetail> example = AttendanceRecordDetail.createExample();
        example.createCriteria().andEqualTo("studentId",studentId).andIn("recordId",recordIds);
        attendanceRecordDetailService.deleteByExample(example);
        updateTotalAmount(recordIds);

    }
}